#ifndef THREADSAFEMAP_HPP_
#define THREADSAFEMAP_HPP_

#include <map>
#include <vector>
#include "system/thread/Mutex.hpp"

namespace KitContainer
{
	template <class KEY, class VALUE>
	class ThreadSafeMap
	{
	public:
		bool contains(KEY iKey);
		void insert(KEY iKey, VALUE iValue);
		std::vector<KEY> keys();
		void remove(KEY iKey);
		VALUE get(KEY iKey);

	private:
		std::map<KEY, VALUE> _m;
		SystemThread::Mutex _mutex;
	};
}

namespace KitContainer
{
		template <class KEY, class VALUE>
		bool ThreadSafeMap<KEY, VALUE>::contains(KEY iKey)
		{
			bool aResult = false;
			_mutex.lock();
			{
				if(_m.count(iKey) > 0)
					aResult = true;
			}
			_mutex.unlock();
			return aResult;
		}

		template <class KEY, class VALUE>
		void ThreadSafeMap<KEY, VALUE>::insert(KEY iKey, VALUE iValue)
		{
			_mutex.lock();
			{
				_m.insert(std::pair<KEY, VALUE>(iKey, iValue));
			}
			_mutex.unlock();
		}

		template <class KEY, class VALUE>
		std::vector<KEY> ThreadSafeMap<KEY, VALUE>::keys()
		{
			std::vector<KEY> aKeys;
			_mutex.lock();
			{
				typename std::map<KEY, VALUE>::iterator itr = _m.begin();
				while(itr != _m.end())
				{
					aKeys.push_back(itr->first);
					itr++;
				}
			}
			_mutex.unlock();
			return aKeys;
		}

		template <class KEY, class VALUE>
		void ThreadSafeMap<KEY, VALUE>::remove(KEY iKey)
		{
			_mutex.lock();
			{
				_m.erase(iKey);
			}
			_mutex.unlock();
		}

		template <class KEY, class VALUE>
		VALUE ThreadSafeMap<KEY, VALUE>::get(KEY iKey)
		{
			VALUE aV;
			_mutex.lock();
			{
				aV = _m[iKey];
			}
			_mutex.unlock();
			return aV;
		}
}

#endif /* THREADSAFEQUEUE_HPP_ */
